﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace GrayParrot.Core.Json
{
    public class PropertyNameChangeConverter : JsonConverter
    {
        public string NameToConvert { get; set; }
        public string ConvertingName { get; set; }

        public PropertyNameChangeConverter()
        {

        }

        public PropertyNameChangeConverter(string nameToConvert, string convertingName)
        {
            NameToConvert = nameToConvert;
            ConvertingName = convertingName;
        } 

        public override bool CanConvert(Type objectType)
        {
            return objectType.IsClass;
        }

        public override bool CanRead
        {
            get { return true; }
        }
        public override bool CanWrite
        {
            get { return true; }
        }

        //public override bool CanConvert(Type objectType)
        //{
        //    return _types.Any(t => t == objectType);
        //}

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            object instance = objectType.GetConstructor(Type.EmptyTypes).Invoke(null);
            PropertyInfo[] props = objectType.GetProperties();

            JObject jo = JObject.Load(reader);
            foreach (JProperty jp in jo.Properties())
            {
                if (jp.Name.Equals(this.NameToConvert, StringComparison.InvariantCultureIgnoreCase))
                {
                    PropertyInfo prop = props.FirstOrDefault(pi =>
                        pi.CanWrite && string.Equals(pi.Name, this.ConvertingName, StringComparison.OrdinalIgnoreCase));

                    if (prop != null)
                        prop.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
                }
            }

            return instance;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            JObject t = JObject.FromObject(value);

            if (t.Type != JTokenType.Object)
            {
                t.WriteTo(writer);
            }
            else
            {
                JObject o = (JObject)t;
                IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();

                o.WriteTo(writer);
            }
        }
    }
}
